shader13.c
#version 460
#pragma vp_name       REX Engine - Fragment
#pragma vp_entryPoint oe_rex_imageLayer_FS
#pragma vp_location   fragment_coloring
#pragma vp_order      0.5
#pragma import_defines(OE_TERRAIN_RENDER_IMAGERY)
#pragma import_defines(OE_TERRAIN_MORPH_IMAGERY)
#pragma import_defines(OE_TERRAIN_BLEND_IMAGERY)
#pragma import_defines(OE_TERRAIN_CAST_SHADOWS)
#pragma import_defines(OE_IS_PICK_CAMERA)
#pragma import_defines(OE_IS_SHADOW_CAMERA)
#pragma import_defines(OE_IS_DEPTH_CAMERA)
#define VP_STAGE_FRAGMENT
uniform sampler2D oe_layer_tex;
uniform int       oe_layer_uid;
uniform int       oe_layer_order;
#ifdef OE_TERRAIN_MORPH_IMAGERY
uniform sampler2D oe_layer_texParent;
uniform float oe_layer_texParentExists;
vec2 oe_layer_texcParent;
#pragma vp_varying_in vec2 oe_layer_texcParent
float oe_rex_morphFactor;
#pragma vp_varying_in float oe_rex_morphFactor
#endif
vec2 oe_layer_texc;
#pragma vp_varying_in vec2 oe_layer_texc
vec4 oe_layer_tilec;
#pragma vp_varying_in vec4 oe_layer_tilec
float oe_layer_opacity;
#pragma vp_varying_in float oe_layer_opacity
// Vertex Markers:
#define VERTEX_VISIBLE  1
#define VERTEX_BOUNDARY 2
#define VERTEX_HAS_ELEVATION 4
#define VERTEX_SKIRT 8
int oe_terrain_vertexMarker;
#pragma vp_varying_in flat int oe_terrain_vertexMarker
void oe_rex_imageLayer_FS(inout vec4 color)
{
    // if the provoking vertex is marked for discard, skip it:
    if ((oe_terrain_vertexMarker & VERTEX_VISIBLE) == 0)
    {
        discard;
        return;
    }
    // If this is a shadow camera and the terrain doesn't cast shadows, no render:
#if defined(OE_IS_SHADOW_CAMERA) && !defined(OE_TERRAIN_CAST_SHADOWS)
    discard;
    return;
#endif
    // If this is a depth-only camera, skip terrain skirt geometry:
#if defined(OE_IS_DEPTH_CAMERA)
    if ((oe_terrain_vertexMarker & VERTEX_SKIRT) != 0)
    {
        discard;
        return;
    }
#endif // OE_IS_DEPTH_CAMERA
    // if this is a picking camera, reset the color to all zeros:
#ifdef OE_IS_PICK_CAMERA
    color = vec4(0);
#else
    // If imagery rendering is disabled, we're done:
#ifndef OE_TERRAIN_RENDER_IMAGERY
    return;
#endif
    // whether this layer contains texel color (UID<0 means no texture)
    bool isTexelLayer = oe_layer_uid >= 0;
    // whether this is the first layer to render:
    bool isFirstLayer = oe_layer_order == 0;
    vec4 texel = color;
    if (isTexelLayer)
    {
        texel = texture(oe_layer_tex, oe_layer_texc);
#ifdef OE_TERRAIN_MORPH_IMAGERY
        // sample the main texture:
        // sample the parent texture:
        vec4 texelParent = texture(oe_layer_texParent, oe_layer_texcParent);
        // if the parent texture does not exist, use the current texture with alpha=0 as the parent
        // so we can  fade in  an image layer that starts at LOD > 0:
        texelParent = mix(vec4(texel.rgb, 0.0), texelParent, oe_layer_texParentExists);
        // Resolve the final texel color.
        // We have to clamp oe_rex_morphFactor here even though it's clamped in the 
        // vertex shader. Reason unknown.
        texel = mix(texel, texelParent, clamp(oe_rex_morphFactor, 0.0, 1.0));
#endif
        // intergrate thelayer opacity:
        texel.a = texel.a * oe_layer_opacity;
        color.a = 1.0;
    }
#ifdef OE_TERRAIN_BLEND_IMAGERY
    // If this is a first image layer, blend with the incoming terrain color.
    // Otherwise, apply directly and let GL blending do the rest.
    if (isTexelLayer && isFirstLayer)
    {
        color.rgb = texel.rgb*texel.a + color.rgb*(1.0 - texel.a);
    }
    else
    {
        color = texel;
    }
#else
    // No blending? The output is just the texel value.
    color = texel;
#endif // OE_TERRAIN_BLEND_IMAGERY
#endif // OE_IS_PICK_CAMERA
}
